package com.cmcc.pcap.packet.sctp.sctp.xdr;

import com.cmcc.packet.entity.SctpEntity;
import com.cmcc.packet.entity.TcpEntity;
import com.cmcc.pcap.packet.sctp.SctpConnection;
import com.cmcc.pcap.packet.sctp.SctpPacketDecorator;
import com.cmcc.pcap.packet.tcp.TcpConnection;
import com.cmcc.pcap.packet.tcp.TcpPacketDecorator;
import com.cmcc.pcap.packet.util.DateUtil;
import com.cmcc.pcap.packet.util.PacketAnalysisConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.SctpPacket;
import org.pcap4j.packet.TcpPacket;
import org.pcap4j.packet.namednumber.SctpChunkType;

import java.text.ParseException;
import java.util.*;

public class SctpXdrGenerate {
	private static Logger logger = LogManager.getLogger(SctpXdrGenerate.class);
	public List<SctpEntity> generate(SctpConnection sctpConnection1, String taskId) {
		/*
		SCTP协议解析，每次连接对应一条入库数据
		 */

		List<SctpEntity> xdrsctpEntityList = new ArrayList<>();
		SctpConnection sctpConnection = sctpConnection1;

		logger.debug("this is sctp xdr generate !");
		SctpEntity xdrsctpentity = new SctpEntity();

		/*  写入taskid  */
		xdrsctpentity.setTaskId(Integer.parseInt(taskId));

		/*  写入protocol type  */
		xdrsctpentity.setProtocolType("SCTP");

		//将有数据的sctp报文保存下来，最多保存前8个报文
		ArrayList<SctpPacket> altemp = new ArrayList<>();
		Integer altemp_length = 0;
		for(SctpPacketDecorator tpt:sctpConnection.retransmissionDataMergeAl){
			if(tpt.sctpPacket.getHeader().getChunks().get(0).getType().equals(SctpChunkType.DATA)){
				altemp.add(tpt.sctpPacket);
				++altemp_length;
			}
			if(altemp_length == 8)
				break;
		}
		xdrsctpentity.setSctpPackets(altemp);

		try {
			saveSctpConnectionToSctpEntityList(sctpConnection,xdrsctpentity);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			logger.error(e.getCause(), e);
		}

		//将每个httpEntity加入httpEntityList中，调用SaveHttpTransactionInfo的save方法保存到数据库中
		xdrsctpEntityList.add(xdrsctpentity);

		/**
		 * Interface
		 * ProcedureStartTime
		 * ProcedureEndTime
		 * ProtocolType
		 * AppType
		 * AppSubType
		 * IPAddressType
		 * UserIPv4
		 * UserIPv6
		 * ......
		 *
		 *
		 */
		return xdrsctpEntityList;
	}

	public void saveSctpConnectionToSctpEntityList(SctpConnection sctpConnection,SctpEntity xdrsctpentity) throws ParseException{

		int length = sctpConnection.retransmissionDataMergeAl.size();
		logger.debug("sctpConnection length:"+length);
		
		if(length==0) {
			xdrsctpentity=null;
			return;
		}
			
		SctpPacketDecorator tpdStart = sctpConnection.retransmissionDataMergeAl.get(0);
		SctpPacketDecorator tpdEnd = sctpConnection.retransmissionDataMergeAl.get(length-1);

		//计算procedure_start_time
		long timestamp_procedure_start_time = tpdStart.timestamp.getTime();
        Date procedureStartTime = DateUtil.formatTimestamp(timestamp_procedure_start_time);
		xdrsctpentity.setProcedureStartTime(procedureStartTime);

		//计算procedure_end_time
		long timestamp_procedure_end_time = tpdEnd.timestamp.getTime();
        Date procedureEndTime = DateUtil.formatTimestamp(timestamp_procedure_end_time);
		xdrsctpentity.setProcedureEndTime(procedureEndTime);

		//填写interface
		Integer interFace = 11;
		xdrsctpentity.setInterfaceCode(interFace);

		//填写ip_address_type,ipv4是0,ipv6是1
		xdrsctpentity.setIpAddressType(0);

		// 找到连接的connectionKey直接填写源地址和目的地址
        String[] connectionKey = sctpConnection.connectionKey.split("-");
        String[] usersocket = connectionKey[0].split(":");
        String[] serversocket = connectionKey[1].split(":");

        String userIpv4;
        String userIpv6;
        Integer userPort;

        String appServerIpIpv4;
        String appServerIpIpv6;
        Integer appServerPort;

        if(usersocket.length>2) {
        	//填写终端用户的ipv6地址和端口
        	String[] useriplist = Arrays.copyOf(usersocket, usersocket.length-1);
        	userIpv6 = String.join(":", useriplist);
        	userPort =  Integer.valueOf(usersocket[8]);

        	xdrsctpentity.setUserIpv6(userIpv6);
        	xdrsctpentity.setUserPort(userPort);

        	// 填写ip_address_type,ipv4是0,ipv6是1
        	xdrsctpentity.setIpAddressType(1);

        }
        else {
        	//填写终端用户的ipv4地址和端口
        	userIpv4 = usersocket[0];
        	userIpv4 = userIpv4.replace("/", "");
        	userPort = Integer.valueOf(usersocket[1]);

        	xdrsctpentity.setUserIpv4(userIpv4);
        	xdrsctpentity.setUserPort(userPort);

        	// 填写ip_address_type,ipv4是0,ipv6是1
        	xdrsctpentity.setIpAddressType(0);

        }


        if(serversocket.length>2) {
        	//填写服务端用户的ipv6地址和端口
        	String[] appserveriplist = Arrays.copyOf(serversocket, serversocket.length-1);
        	appServerIpIpv6 = String.join(":", appserveriplist);
        	appServerPort =  Integer.valueOf(serversocket[8]);

        	xdrsctpentity.setAppServerIpIpv6(appServerIpIpv6);
        	xdrsctpentity.setAppServerPort(appServerPort);
        }
        else {
        	//填写服务端用户的ipv4地址和端口
        	appServerIpIpv4 = serversocket[0];
        	appServerIpIpv4 = appServerIpIpv4.replace("/", "");
        	appServerPort = Integer.valueOf(serversocket[1]);

        	xdrsctpentity.setAppServerIpIpv4(appServerIpIpv4);
        	xdrsctpentity.setAppServerPort(appServerPort);
        }



		/**
		 * 报文统计
		 * UL Data上行流量
		 * DL Data下行流量
		 * UL IP Packet上行IP包数
		 * DL IP Packet下行IP包数
		 * UL_IP_FRAG_PACKETS上行IP包的分片数
		 * DL_IP_FRAG_PACKETS下行IP包的分片数
		 * SCTP INIT Num：SCTP INIT报文个数
		 * SCTP INIT ACK Num：SCTP INIT ACK报文个数
		 * SCTP COOKIE ECHO Num：SCTP COOKIE ECHO报文个数
		 * SCTP COOKIE ACK Num：SCTP COOKIE ACK报文个数
		 * SCTP HEARTBEAT Num：SCTP HEARTBEAT报文个数
		 * SCTP HEARTBEAT ACK Num：SCTP HEARTBEAT ACK报文个数
		 */

		SctpStatistics sctpstat = new SctpStatistics(sctpConnection);
		sctpstat.SctpStat();
		xdrsctpentity.setUlData(sctpstat.UL_Data);
		xdrsctpentity.setDlData(sctpstat.DL_Data);
		xdrsctpentity.setUlIpPacket(sctpstat.UL_IP_Packet);
		xdrsctpentity.setDlIpPacket(sctpstat.DL_IP_Packet);
		xdrsctpentity.setSctpInitNum(sctpstat.SCTP_INIT_Num);
		xdrsctpentity.setSctpInitAckNum(sctpstat.SCTP_INIT_ACK_Num);
		xdrsctpentity.setSctpCookieEchoNum(sctpstat.SCTP_COOKIE_ECHO_Num);
		xdrsctpentity.setSctpCookieAckNum(sctpstat.SCTP_COOKIE_ACK_Num);
		xdrsctpentity.setSctpHeartbeatNum(sctpstat.SCTP_HEARTBEAT);
		xdrsctpentity.setSctpHeartbeatAckNum(sctpstat.SCTP_HEARTBEAT_ACK);

	}
}